﻿using System.Collections.Specialized;
using System.IO;
using DBFile.Core.Web;
using DBFile.Providers;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace DBFile.MSTest
{
    
    [TestClass]
    public class FileSystemProviderTest
    {
        public FileSystemProviderTest()
        {
            //
            // TODO: Add constructor logic here
            //
        }

        private TestContext testContextInstance;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #region Additional test attributes
        //
        // You can use the following additional attributes as you write your tests:
        //
        // Use ClassInitialize to run code before running the first test in the class
        // [ClassInitialize()]
        // public static void MyClassInitialize(TestContext testContext) { }
        //
        // Use ClassCleanup to run code after all tests in a class have run
        // [ClassCleanup()]
        // public static void MyClassCleanup() { }
        //
        // Use TestInitialize to run code before running each test 
        // [TestInitialize()]
        // public void MyTestInitialize() { }
        //
        // Use TestCleanup to run code after each test has run
        // [TestCleanup()]
        // public void MyTestCleanup() { }
        //
        #endregion

        [TestInitialize()]
        public void Initialize()
        {
            string tempDir = "E:\\Temp";
            string tempTextFileName = Path.Combine(tempDir, "test.txt");
            string tempTextFileName2 = Path.Combine(tempDir, "test2.txt");

            TestContext.Properties.Add("tempDir", tempDir);
            TestContext.Properties.Add("tempTextFileName", tempTextFileName);
            TestContext.Properties.Add("tempTextFileName2", tempTextFileName2);

            NameValueCollection configValue = new NameValueCollection();
            configValue.Add("name", "FileSystemProvider");
            configValue.Add("type", "DBFile.Providers.FileSystemProvider, DBFile.FileSystemProvider");
            configValue.Add("repositoryPath", "E:\\Temp");

            DBFile.Providers.FileSystemProvider provider = new FileSystemProvider();
            provider.Initialize("FileSystemProvider", configValue);
             
            TestContext.Properties.Add("Provider", provider);
        }

        [TestCleanup()]
        public void Cleanup()
        {
            string tempTextFileName = testContextInstance.Properties["tempTextFileName"].ToString();
            string tempTextFileName2 = testContextInstance.Properties["tempTextFileName2"].ToString();

            File.Delete(tempTextFileName);
            File.Delete(tempTextFileName2);
        }
        
        [TestMethod]
        public void Exists()
        {
            FileSystemProvider provider = TestContext.Properties["Provider"] as DBFile.Providers.FileSystemProvider;
            string tempTextFileName = TestContext.Properties["tempTextFileName"].ToString();

            CreateTextFile(provider, tempTextFileName, "This is a test");

            Assert.IsTrue(provider.Exists(tempTextFileName));
        }       

        [TestMethod]
        public void Copy()
        {
            FileSystemProvider provider = TestContext.Properties["Provider"] as DBFile.Providers.FileSystemProvider;
            string tempTextFileName = TestContext.Properties["tempTextFileName"].ToString();
            string tempTextFileName2 = TestContext.Properties["tempTextFileName2"].ToString();

            CreateTextFile(provider, tempTextFileName, "This is a test");

            int result = provider.Copy(tempTextFileName, tempTextFileName, false);

            Assert.AreEqual(0, result);
            
            result = provider.Copy(tempTextFileName, tempTextFileName2, true);

            Assert.IsTrue(File.Exists(tempTextFileName2));
            Assert.AreEqual(1, result);

            result = provider.Copy(tempTextFileName, tempTextFileName2, true);

            Assert.AreEqual(1, result);

        }

        [TestMethod]
        public void Insert()
        {
            FileSystemProvider provider = TestContext.Properties["Provider"] as DBFile.Providers.FileSystemProvider;
            string tempTextFileName = TestContext.Properties["tempTextFileName"].ToString();

            Assert.IsFalse(provider.Exists(tempTextFileName));

            byte[] content = System.Text.ASCIIEncoding.UTF8.GetBytes("This is a test");
            int result = provider.Insert(tempTextFileName, content, DBFile.Core.DBFile.GetContentType(".txt"), content.Length);

            Assert.IsTrue(provider.Exists(tempTextFileName));
            Assert.AreEqual(1, result);
        }

        [TestMethod]
        public void Insert2()
        {
            FileSystemProvider provider = TestContext.Properties["Provider"] as DBFile.Providers.FileSystemProvider;
            string tempTextFileName = TestContext.Properties["tempTextFileName"].ToString();

            Assert.IsFalse(provider.Exists(tempTextFileName));

            byte[] content = System.Text.ASCIIEncoding.UTF8.GetBytes("This is a test");
            int result = provider.Insert(tempTextFileName, content, DBFile.Core.DBFile.GetContentType(".txt"), content.Length, false);

            Assert.IsTrue(provider.Exists(tempTextFileName));
            Assert.AreEqual(1, result);

            result = provider.Insert(tempTextFileName, content, DBFile.Core.DBFile.GetContentType(".txt"), content.Length, false);
            Assert.IsTrue(provider.Exists(tempTextFileName));
            Assert.AreEqual(0, result);
        }

        [TestMethod]
        public void Update()
        {
            FileSystemProvider provider = TestContext.Properties["Provider"] as DBFile.Providers.FileSystemProvider;
            string tempTextFileName = TestContext.Properties["tempTextFileName"].ToString();
            string originalText = "This is a test";

            CreateTextFile(provider, tempTextFileName, originalText);

            string actualText = File.ReadAllText(tempTextFileName);
            Assert.AreEqual(originalText, actualText);

            string updatedText = "This is a test - editted";
            byte[] content = System.Text.ASCIIEncoding.UTF8.GetBytes(updatedText);
            int result = provider.Update(tempTextFileName, content, DBFile.Core.DBFile.GetContentType(".txt"), content.Length);

            Assert.IsTrue(provider.Exists(tempTextFileName));
            Assert.AreEqual(1, result);

            actualText = File.ReadAllText(tempTextFileName);
            Assert.AreEqual(updatedText, actualText);

        }

        [TestMethod]
        public void Delete()
        {
            FileSystemProvider provider = TestContext.Properties["Provider"] as DBFile.Providers.FileSystemProvider;
            string tempTextFileName = TestContext.Properties["tempTextFileName"].ToString();
            string originalText = "This is a test";
            CreateTextFile(provider, tempTextFileName, originalText);

            int result = provider.Delete(tempTextFileName);

            Assert.AreEqual(1, result);

            result = provider.Delete(tempTextFileName);

            Assert.AreEqual(0, result);
        }

        [TestMethod]
        public void GetList()
        {
            FileSystemProvider provider = TestContext.Properties["Provider"] as DBFile.Providers.FileSystemProvider;
            string tempDir = TestContext.Properties["tempDir"].ToString();
            string tempTextFileName = TestContext.Properties["tempTextFileName"].ToString();
            string tempTextFileName2 = TestContext.Properties["tempTextFileName2"].ToString();

            CreateTextFile(provider, tempTextFileName, "Test File 1");
            CreateTextFile(provider, tempTextFileName2, "Test File 2");

            string[] fileNames = provider.GetFileNameList();

            Assert.IsTrue(fileNames.Length >= 2);
        }

        [TestMethod]
        public void Get()
        {
            FileSystemProvider provider = TestContext.Properties["Provider"] as DBFile.Providers.FileSystemProvider;
            string tempTextFileName = TestContext.Properties["tempTextFileName"].ToString();

            CreateTextFile(provider, tempTextFileName, "Test File 1");

            using (HttpPostedFile file = provider.Get<HttpPostedFile>(tempTextFileName))
            {
                Assert.IsNotNull(file);
                Assert.AreEqual(tempTextFileName, file.FileName);
                Assert.AreEqual(DBFile.Core.DBFile.GetContentType(".txt"), file.ContentType);
                Assert.AreEqual(11, file.ContentLength);
                Assert.IsNotNull(file.InputStream);
            }
        }

        private void CreateTextFile(FileSystemProvider provider, string filename, string content)
        {
            Assert.IsFalse(provider.Exists(filename));

            File.WriteAllText(filename, content);

            Assert.IsTrue(provider.Exists(filename));
        }
    }
}
